<template>
  <div class="count-to-wrapper">
    <slot name="left"/>
    <p class="content-outer"><span :class="['count-to-count-text', countClass]" :id="counterId">{{ init }}</span><i :class="['count-to-unit-text', unitClass]">{{ unitText }}</i></p>
    <slot name="right"/>
  </div>
</template>

<script>
import CountUp from 'countup'
import './index.less'
export default {
	name: 'CountTo',
	props: {
		init: {
			type: Number,
			default: 0,
		},
		/**
		 * @description 起始值，即动画开始前显示的数值
		 */
		startVal: {
			type: Number,
			default: 0,
		},
		/**
		 * @description 结束值，即动画结束后显示的数值
		 */
		end: {
			type: Number,
			required: true,
		},
		/**
		 * @description 保留几位小数
		 */
		decimals: {
			type: Number,
			default: 0,
		},
		/**
		 * @description 分隔整数和小数的符号，默认是小数点
		 */
		decimal: {
			type: String,
			default: '.',
		},
		/**
		 * @description 动画持续的时间，单位是秒
		 */
		duration: {
			type: Number,
			default: 2,
		},
		/**
		 * @description 动画延迟开始的时间，单位是秒
		 */
		delay: {
			type: Number,
			default: 0,
		},
		/**
		 * @description 是否禁用easing动画效果
		 */
		uneasing: {
			type: Boolean,
			default: false,
		},
		/**
		 * @description 是否使用分组，分组后每三位会用一个符号分隔
		 */
		usegroup: {
			type: Boolean,
			default: false,
		},
		/**
		 * @description 用于分组(usegroup)的符号
		 */
		separator: {
			type: String,
			default: ',',
		},
		/**
		 * @description 是否简化显示，设为true后会使用unit单位来做相关省略
		 */
		simplify: {
			type: Boolean,
			default: false,
		},
		/**
		 * @description 自定义单位，如[3, 'K+'], [6, 'M+']即大于3位数小于6位数的用k+来做省略
		 *              1000即显示为1K+
		 */
		unit: {
			type: Array,
			default() {
				return [[3, 'K+'], [6, 'M+'], [9, 'B+']]
			},
		},
		countClass: {
			type: String,
			default: '',
		},
		unitClass: {
			type: String,
			default: '',
		},
	},
	data() {
		return {
			counter: null,
			unitText: '',
		}
	},
	computed: {
		counterId() {
			return `count_to_${this._uid}`
		},
	},
	methods: {
		getHandleVal(val, len) {
			return {
				endVal: parseInt(val / Math.pow(10, this.unit[len - 1][0])),
				unitText: this.unit[len - 1][1],
			}
		},
		transformValue(val) {
			let len = this.unit.length
			let res = {
				endVal: 0,
				unitText: '',
			}
			if (val < Math.pow(10, this.unit[0][0])) res.endVal = val
			else {
				for (let i = 1; i < len; i++) {
					if (val >= Math.pow(10, this.unit[i - 1][0]) && val < Math.pow(10, this.unit[i][0]))
						res = this.getHandleVal(val, i)
				}
			}
			if (val > Math.pow(10, this.unit[len - 1][0])) res = this.getHandleVal(val, len)
			return res
		},
		getValue(val) {
			let res = 0
			if (this.simplify) {
				let { endVal, unitText } = this.transformValue(val)
				this.unitText = unitText
				res = endVal
			} else {
				res = val
			}
			return res
		},
	},
	mounted() {
		this.$nextTick(() => {
			let endVal = this.getValue(this.end)
			this.counter = new CountUp(this.counterId, this.startVal, endVal, this.decimals, this.duration, {
				useEasing: !this.uneasing,
				useGrouping: this.useGroup,
				separator: this.separator,
				decimal: this.decimal,
			})
			setTimeout(() => {
				if (!this.counter.error) this.counter.start()
			}, this.delay)
		})
	},
	watch: {
		end(newVal) {
			let endVal = this.getValue(newVal)
			this.counter.update(endVal)
		},
	},
}
</script>
